package com.sise.aio和bio和nio.nio.基本nio;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author idea
 * @data 2019/4/6
 */
public class Server implements Runnable {

    public int port;

    private ServerSocketChannel serverSocketChannel;

    private Selector selector;

    public Server(int port) throws IOException {
        this.port = port;
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        //设置为非堵塞模式
        serverSocketChannel.configureBlocking(false);
        //让channel注册到选择器上边，并且监听相应的选择器事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }


    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                //堵塞等待
                selector.select();
                Set<SelectionKey> set = selector.selectedKeys();
                Iterator it = set.iterator();
                while (it.hasNext()) {
                    it.remove();
                    //对于选择器的状态进行判断，然后做出不同的处理
                    dispatch((SelectionKey) it.next());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void dispatch(SelectionKey key) throws IOException {
        //判断选择器是否处于待接收状态
        if (key.isAcceptable()) {
            register(key);
        } else if (key.isReadable()) {
            read();
        } else if (key.isWritable()) {
            write();
        }
    }

    /**
     * 写数据的操作处理
     */
    private void write() {

    }

    /**
     * 读取信息的操作处理
     */
    private void read() {

    }

    private void register(SelectionKey key) throws IOException {
        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
        // 获得和客户端连接的通道
        SocketChannel channel = ssc.accept();
        channel.configureBlocking(false);
        //客户端通道注册到selector 上
        channel.register(this.selector, SelectionKey.OP_READ);
    }
}
